package com.example.navigation.service;

import com.example.navigation.config.BaiduMapsConfig;
import com.example.navigation.dto.NavigationResponse;
import com.example.navigation.dto.PlaceSearchResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;

import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class BaiduMapsService {

    private final BaiduMapsConfig config;
    private final OkHttpClient httpClient;
    private final ObjectMapper objectMapper;

    @Autowired
    public BaiduMapsService(BaiduMapsConfig config) {
        this.config = config;
        this.httpClient = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .build();
        
        // 配置ObjectMapper以忽略未知属性和处理空值
        this.objectMapper = new ObjectMapper()
                .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
                .configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
                .configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
    }

    /**
     * 获取驾车导航路线
     * @param origin 起点坐标，格式为"纬度,经度"，例如"39.915,116.404"
     * @param destination 终点坐标，格式为"纬度,经度"
     * @param alternatives 是否返回备选路线，默认为true
     * @return 导航响应对象
     */
    public NavigationResponse getDrivingDirections(String origin, String destination, boolean alternatives) {
        try {
            // 构建API URL，直接使用指定的格式
            String url = String.format("%s/direction/v2/driving?origin=%s&destination=%s&ak=%s&alternatives=%d",
                    config.getApiUrl(),
                    origin,
                    destination,
                    config.getApiKey(),
                    alternatives ? 1 : 0);

            log.info("Calling Baidu Maps API: {}", url);
            
            Request request = new Request.Builder()
                    .url(url)
                    .get()
                    .build();

            try (Response response = httpClient.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    log.error("Baidu Maps API request failed: {}", response);
                    throw new RuntimeException("Baidu Maps API request failed with code: " + response.code());
                }

                String responseBody = response.body().string();
                log.debug("Baidu Maps API response: {}", responseBody);
                
                try {
                    return objectMapper.readValue(responseBody, NavigationResponse.class);
                } catch (JsonProcessingException e) {
                    log.error("Failed to parse API response: {}", e.getMessage());
                    log.error("Response body: {}", responseBody);
                    throw new RuntimeException("Failed to parse API response", e);
                }
            }
        } catch (IOException e) {
            log.error("Error calling Baidu Maps API", e);
            throw new RuntimeException("Error calling Baidu Maps API", e);
        }
    }
    
    /**
     * 搜索地点
     * @param keyword 搜索关键词
     * @param region 搜索区域，默认为"全国"
     * @return 地点搜索响应对象
     */
    public PlaceSearchResponse searchPlace(String keyword, String region) {
        try {
            // 构建API URL
            String url = UriComponentsBuilder.fromHttpUrl(config.getApiUrl() + "/place/v2/search")
                    .queryParam("query", keyword)
                    .queryParam("region", region)
                    .queryParam("output", "json")
                    .queryParam("ak", config.getApiKey())
                    .build()
                    .toUriString();

            log.info("Calling Baidu Maps Place Search API: {}", url);
            
            Request request = new Request.Builder()
                    .url(url)
                    .get()
                    .build();

            try (Response response = httpClient.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    log.error("Baidu Maps Place Search API request failed: {}", response);
                    throw new RuntimeException("Baidu Maps Place Search API request failed with code: " + response.code());
                }

                String responseBody = response.body().string();
                log.debug("Baidu Maps Place Search API response: {}", responseBody);
                
                try {
                    return objectMapper.readValue(responseBody, PlaceSearchResponse.class);
                } catch (JsonProcessingException e) {
                    log.error("Failed to parse Place Search API response: {}", e.getMessage());
                    log.error("Response body: {}", responseBody);
                    throw new RuntimeException("Failed to parse Place Search API response", e);
                }
            }
        } catch (IOException e) {
            log.error("Error calling Baidu Maps Place Search API", e);
            throw new RuntimeException("Error calling Baidu Maps Place Search API", e);
        }
    }
} 